package cn.jolyoulu.adminweb.service.impl;

import cn.jolyoulu.adminweb.entity.bo.form.SysUserFormBO;
import cn.jolyoulu.adminweb.entity.bo.query.SysUserQueryBO;
import cn.jolyoulu.adminweb.entity.vo.SysUserVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.jolyoulu.adminweb.service.ApiSysUserService;
import cn.jolyoulu.cmnservice.constant.ServiceRedisConstant;
import cn.jolyoulu.cmnservice.entity.po.HoldUser;
import cn.jolyoulu.cmnservice.entity.po.SysRole;
import cn.jolyoulu.cmnservice.entity.po.SysUser;
import cn.jolyoulu.cmnservice.serivce.SysRoleService;
import cn.jolyoulu.cmnservice.serivce.SysUserService;
import cn.jolyoulu.cmnservice.utils.HoldUserUtils;
import cn.jolyoulu.common.core.utils.encryption.MD5Utils;
import cn.jolyoulu.common.core.utils.other.RandomUtils;
import cn.jolyoulu.common.mybatis.plus.plugin.page.JlPage;
import cn.jolyoulu.common.redis.utils.RedisUtils;
import cn.jolyoulu.common.web.enums.GlobalExpType;
import cn.jolyoulu.common.web.excption.GlobalException;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author LuZhouJin
 * @Date 2023/3/17
 */
@Slf4j
@Service
public class ApiSysUserServiceImpl implements ApiSysUserService {

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private ApiSysUserService apiSysUserService;

    @Autowired
    private RedisUtils redisUtils;

    @Override
    public JlPage<SysUserVO> pageList(SysUserQueryBO bo) {
        JlPage<SysUserVO> res = JlPage.execute(bo.getPage(), bo.getPageSize(), () -> {
            LambdaQueryWrapper<SysUser> ew = new LambdaQueryWrapper<>();
            if (StringUtils.isNotBlank(bo.getAccount())) {
                ew.eq(SysUser::getAccount, bo.getAccount());
            }
            if (Objects.nonNull(bo.getSex())) {
                ew.eq(SysUser::getSex, bo.getSex());
            }
            if (StringUtils.isNotBlank(bo.getEmail())) {
                ew.eq(SysUser::getEmail, bo.getEmail());
            }
            if (StringUtils.isNotBlank(bo.getPhone())) {
                ew.eq(SysUser::getPhone, bo.getPhone());
            }
            if (Objects.nonNull(bo.getStatus())) {
                ew.eq(SysUser::getStatus, bo.getStatus());
            }
            List<SysUser> list = sysUserService.list(ew);
            return list.stream().map(SysUserVO::new).collect(Collectors.toList());
        });
        return res;
    }

    @Override
    public SysUserVO getById(String id) {
        SysUser sysUser = sysUserService.getById(id);
        //获取拥有角色
        if (Objects.nonNull(sysUser)) {
            List<SysRole> roles = sysRoleService.selectByUserId(sysUser.getId());
            return new SysUserVO(sysUser, roles);
        }
        return new SysUserVO(sysUser);
    }

    @Override
    @Transactional
    public void add(SysUserFormBO sysUserFormBO) {
        //检查账号唯一
        SysUser check = sysUserService.getByAccount(sysUserFormBO.getAccount());
        if (Objects.nonNull(check)) {
            throw new GlobalException(GlobalExpType.USER_REGISTER);
        }
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(sysUserFormBO, sysUser);
        //密码处理
        String salt = RandomUtils.nextStr(4);
        String encodePwd = MD5Utils.encode(sysUserFormBO.getPassword() + salt);
        sysUser.setPassword(encodePwd);
        sysUser.setSalt(salt);
        sysUser.fillUpdate().fillCreat();
        sysUserService.save(sysUser);
        //关联角色
        HoldUser holdUser = HoldUserUtils.get();
        if (Objects.nonNull(sysUserFormBO.getRoleIds()) && !sysUserFormBO.getRoleIds().isEmpty() && holdUser.hasPermission("sys:role:allot")) {
            apiSysUserService.allotRole(sysUser.getId(), sysUserFormBO.getRoleIds());
        }
    }

    @Override
    @Transactional
    public void update(SysUserFormBO sysUserFormBO) {
        //不能修改的属性设null
        sysUserFormBO.setAccount(null);
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(sysUserFormBO, sysUser);
        if (StringUtils.isNotBlank(sysUser.getPassword())) {
            //密码处理
            String salt = RandomUtils.nextStr(4);
            String encodePwd = MD5Utils.encode(sysUserFormBO.getPassword() + salt);
            sysUser.setPassword(encodePwd);
            sysUser.setSalt(salt);
        }
        sysUser.fillUpdate();
        sysUserService.updateById(sysUser);
        //关联角色
        HoldUser holdUser = HoldUserUtils.get();
        if (Objects.nonNull(sysUserFormBO.getRoleIds()) && !sysUserFormBO.getRoleIds().isEmpty() && holdUser.hasPermission("sys:role:allot")) {
            apiSysUserService.allotRole(sysUser.getId(), sysUserFormBO.getRoleIds());
        }
    }

    @Override
    @Transactional
    public void delByIds(List<String> ids) {
        for (String id : ids) {
            sysUserService.removeById(id);
        }
    }

    @Override
    public void allotRole(String userId, List<String> roleIds) {
        sysUserService.allotRole(userId, roleIds);
        String key = ServiceRedisConstant.getUserRole(userId);
        if (redisUtils.exists(key)) {
            redisUtils.del(key);
        }
    }
}
